/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.cef.designtime.api.changecontrolrule.controlruledef.basic.parser;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.inspur.edp.cef.designtime.api.changecontrolrule.controlruledef.basic.entity.ControlRuleDefItem;
import com.inspur.edp.cef.designtime.api.changecontrolrule.controlruledef.basic.entity.ControlRuleDefinition;
import com.inspur.edp.cef.designtime.api.changecontrolrule.controlruledef.basic.serializer.ControlRuleDefNames;
import com.inspur.edp.cef.designtime.api.json.SerializerUtils;
import java.io.IOException;

import static com.fasterxml.jackson.core.JsonToken.END_ARRAY;
import static com.fasterxml.jackson.core.JsonToken.FIELD_NAME;

/**
 * The JsonParser Of ControlRuleDef
 *
 * @ClassName: ControlRuleDefParser
 * @Author: Benjamin Gong
 * @Date: 2021/1/11 17:13
 * @Version: V1.0
 */
public class ControlRuleDefParser<T extends ControlRuleDefinition>  extends JsonDeserializer<T> {
    @Override
    public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        T ruleDefinition=createRuleDefinition();
        SerializerUtils.readStartObject(jsonParser);
        readSelfInfos(ruleDefinition,jsonParser,deserializationContext);
        SerializerUtils.readEndObject(jsonParser);
        return ruleDefinition;
    }


    private void readSelfInfos(T ruleDefinition, JsonParser jsonParser, DeserializationContext deserializationContext) {
        while (jsonParser.getCurrentToken()==FIELD_NAME) {
            String propName = SerializerUtils.readPropertyName(jsonParser);
            switch (propName) {
                case ControlRuleDefNames.RuleObjectType:
                    ruleDefinition.setRuleObjectType(SerializerUtils.readPropertyValue_String(jsonParser));
                    break;
                case ControlRuleDefNames.SelfControlRules:
                    readSelfControlRules(ruleDefinition, jsonParser, deserializationContext);
                    break;
                case ControlRuleDefNames.ChildControlRules:
                    readChildControlRules(ruleDefinition, jsonParser, deserializationContext);
                    break;
                default:
                    if (readExtendControlRuleProperty(ruleDefinition, propName, jsonParser, deserializationContext) == false)
                        throw new RuntimeException(String.format("ControlRuleDefParser未识别的属性名：%1$s", propName));
                    break;
            }
        }
    }

    private void readSelfControlRules(ControlRuleDefinition ruleDefinition, JsonParser jsonParser, DeserializationContext deserializationContext) {
        SerializerUtils.readStartArray(jsonParser);
        JsonToken tokentype = jsonParser.getCurrentToken();
        if(tokentype!=END_ARRAY)
        {
            while (jsonParser.getCurrentToken() == tokentype || jsonParser.getLastClearedToken() == tokentype) {
                ControlDefItemParser deserializer = new ControlDefItemParser();
                try {
                    ControlRuleDefItem item = deserializer.deserialize(jsonParser, null);
                    //ControlRuleDefItem item = SerializerUtils.readPropertyValue_Object(ControlRuleDefItem.class,jsonParser);
                    ruleDefinition.getSelfControlRules().put(item.getRuleName(),item);
//                    jsonParser.nextToken();
                } catch (IOException e) {
                    throw new RuntimeException("ControlRuleDefItem反序列化失败："+jsonParser.toString(), e);
                }

            }
        }
        SerializerUtils.readEndArray(jsonParser);
    }

    private void readChildControlRules(ControlRuleDefinition ruleDefinition, JsonParser jsonParser, DeserializationContext deserializationContext) {
        SerializerUtils.readStartObject(jsonParser);
        while (jsonParser.getCurrentToken()==FIELD_NAME)
        {
            String childTypeName = SerializerUtils.readPropertyName(jsonParser);
//            Class childRuleType = getChildTypes(childTypeName);
//            ControlRuleDefinition childRuleDefinition= (ControlRuleDefinition) SerializerUtils.readPropertyValue_Object(childRuleType,jsonParser);
            JsonDeserializer childDeserializer = getChildDeserializer(childTypeName);
            try {
                ControlRuleDefinition childRuleDefinition = (ControlRuleDefinition)childDeserializer.deserialize(jsonParser, null);
                ruleDefinition.getChildControlRules().put(childTypeName,childRuleDefinition);
            } catch (IOException e) {
                throw new RuntimeException("ChildControlRule["+ childTypeName +"]反序列化失败："+jsonParser.toString(), e);
            }
        }

        SerializerUtils.readEndObject(jsonParser);
    }

    protected Class getChildTypes(String childTypeName) {
        return ControlRuleDefinition.class;
    }

    protected JsonDeserializer getChildDeserializer(String childTypeName){
        return new ControlRuleDefParser();
    }
    protected boolean readExtendControlRuleProperty(T ruleDefinition, String propName, JsonParser jsonParser, DeserializationContext deserializationContext) {
        return false;
    }

    protected T createRuleDefinition() {
        return (T) new ControlRuleDefinition();
    }
}
